package flex.cc.vehicle_svr.service.impl;

import com.alibaba.fastjson.JSONObject;
import flex.cc.PublicUtil;
import flex.cc.common.utils.HttpClientUtil;
import flex.cc.order.manage.dto.order.OrderMainEntity;
import flex.cc.order.manage.dto.order.OrderTrackEntity;
import flex.cc.order.manage.enums.StatusEnum;
import flex.cc.order.manage.service.OrderTrackService;
import flex.cc.util.EncryptionDecryption;
import flex.cc.vehicle_svr.vo.ResponseVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @author wkangle
 * @className AsyncCancelNoticeService
 * @description 上游异步取消通知service
 * @time 2022-01-04 15:26:16
 */
@Service
public class AsyncCancelNoticeService {
    private static final Logger logger = LoggerFactory.getLogger(AsyncCancelNoticeService.class);

    @Autowired
    private OrderTrackService orderTrackService;

    /**
     * @param body                       取消接口参数
     * @param rescuer_request_cancel_url 请求URL
     * @param orderMainEntity            服务单实体
     * @param sourceName01               操作人
     * @return
     * @description 上游异步取消
     * @author wkangle
     * @time 2022-01-04 14:40:51
     * @exception/throws
     */

    // 取消通知接口参数
    //Map<String, Object> body = new HashMap<String, Object>();
    //Map<String, String> requestHeader = new HashMap<String, String>();
    //Map<String, String> requestBody = new HashMap<String, String>();
    //requestHeader.put("partnerCode", CommonUtils.PARTNERCODE);
    //requestHeader.put("clientId", CommonUtils.CLIENTID);
    //requestHeader.put("requestCode", "RescuerRequestCancel");
    //body.put("requestHeader", requestHeader);
    //requestBody.put("ownerOrderNo", orderMain.getOwnerOrderNo()); // 救援单号(最大长度30)
    //requestBody.put("salvationStatus", null); // 救援状态（见附录）工单请求接口时的：救援状态。
    //requestBody.put("serviceAmount", null); // 实际救援服务金额：传默认值：0。有值时格式（整数数字），例：125
    //requestBody.put("cancelReason", null); // 服务商备注（此接口取消前，救援商侧需与客户沟通达成一致，文字描述沟通结果为接口字段内容值）
    //requestBody.put("cancelTime", null); // 取消时间，时间 YYYY-MM-dd HH:mm:ss
    //requestBody.put("cancelMsg", null); // 取消状态说明（见附录）工单请求接口时的：取消状态—代码对应说明。
    //requestBody.put("cancelCode", null); // 取消状态代码（见附录）工单请求接口时的：取消状态—代码。
    //requestBody.put("totalDistance", null); // 预计总行程距离（单位：m）：无法取值时请商务与业务老师沟通确认，可传0，正常值例如：23000
    //requestBody.put("usedDistance", null); // 已行驶距离（单位：m）,无法取值时请商务与业务老师沟通确认，可传0，正常值例如：23000
    //requestBody.put("elapsedTime", null); // 已用时间，保司请求下单接口的请求时间至取消发起时间点（单位：秒），十分钟例如：600

    // 取消通知接口加密
    //EncryptionDecryption des = new EncryptionDecryption();
    //String jsonStr = JSON.toJSONString(body);
    //logger.info("取消通知 ==> 加密前的回传报文=" + jsonStr);
    //body = des.encrypt(jsonStr);
    //logger.info("取消通知 ==> 加密后的回传报文=" + jsonBody);
    @Async
    public Map<String, Object> asyncCancelNotice(String body, String rescuer_request_cancel_url, OrderMainEntity orderMainEntity, String sourceName01) {
        Map<String, Object> responseMap = new HashMap<>();
        AtomicReference<Integer> counter = new AtomicReference<Integer>(0);
        String temp_code = "9999"; // 请求上游取消通知接口返回的code码
        String responseMsg = "";
        String result = "";

        while (counter.get() < 3) {
            result = HttpClientUtil.sendHttpPost(rescuer_request_cancel_url, body, null);
            logger.info("取消通知结果 ==> result: " + result);
            if (result == null || "".equals(result)) {
                counter.compareAndSet(counter.get(), counter.get() + 1);
            } else {
                try {
                    EncryptionDecryption des = new EncryptionDecryption();
                    result = des.decrypt(result.trim(), "UTF-8");
                    logger.info("渠道商取消通知接口返回响应报文解密=" + result);
                    JSONObject json = JSONObject.parseObject(result);
                    String responseCode = json.get("responseCode").toString();
                    responseMsg = json.get("responseMsg").toString();
                    temp_code = responseCode;
                    if (PublicUtil.isNotEmpty(responseCode)) {
                        counter.compareAndSet(counter.get(), counter.get() + 1);
                    } else {
                        counter.getAndSet(5);
                    }
                } catch (Exception e) {
                    logger.info("渠道商取消通知接口解密异常 =>" + e.getMessage());
                    temp_code = "9998";
                    responseMsg = "上游取消通知接口返回值解密异常";
                    counter.getAndSet(5);
                    e.printStackTrace();
                }
            }
        }

        if (result == null || "".equals(result)) {
            responseMap.put("resultCode", ResponseVo.ERROR_CODE);
            responseMap.put("message", "渠道商取消通知接口调用失败");
            //插入轨迹信息
            // 取消备注；服务取消；任务结束
            saveTrack(orderMainEntity.getOrderNo(),
                    "03",
                    "上游取消通知失败",
                    orderMainEntity.getStatus(),
                    StatusEnum.getName("09"),
                    new Date(),
                    sourceName01);
        } else {
            if ("00".equals(temp_code)) { // 00-成功 01-失败/对应说明
                responseMap.put("resultCode", ResponseVo.SUCCESS_CODE);
                responseMap.put("message", ResponseVo.SUCCESS_MSG);
                saveTrack(orderMainEntity.getOrderNo(),
                        "03",
                        "渠道商取消通知成功",
                        orderMainEntity.getStatus(),
                        StatusEnum.getName("09"),
                        new Date(),
                        sourceName01);
            } else {
                responseMap.put("resultCode", ResponseVo.ERROR_CODE);
                responseMap.put("message", "渠道商取消通知接口返回失败: " + responseMsg);
                //插入轨迹信息
                // 取消备注；服务取消；任务结束
                saveTrack(orderMainEntity.getOrderNo(),
                        "03",
                        "渠道商取消通知失败",
                        orderMainEntity.getStatus(),
                        StatusEnum.getName("09"),
                        new Date(),
                        sourceName01);
            }
        }
        return responseMap;
    }

    /**
     * @param orderNo       服务单号
     * @param trackType     轨迹类型
     * @param trackDesc     轨迹描述
     * @param status        状态
     * @param serviceStatus 下游回传状态描述
     * @param currentDate   当前时间
     * @param sourceName01  操作人
     * @return
     * @description 根据条件保存轨迹
     * @author wkangle
     * @time 2021/10/09 0009 11:13
     * @exception/throws
     */
    private void saveTrack(String orderNo, String trackType, String trackDesc, String status, String serviceStatus, Date currentDate, String sourceName01) {
        // 服务单轨迹表
        OrderTrackEntity orderTrackEntity = new OrderTrackEntity();
        orderTrackEntity.setDataId(UUID.randomUUID().toString().replace("-", ""));
        orderTrackEntity.setOrderNo(orderNo);
        orderTrackEntity.setTrackType(trackType);
        orderTrackEntity.setTrackDesc(trackDesc);
        orderTrackEntity.setStatus(status);
        orderTrackEntity.setServiceStatus(serviceStatus);

        orderTrackEntity.setSynTime(PublicUtil.isNotEmpty(serviceStatus) ? currentDate : null); // 当serviceStatus不为空即该轨迹是“救援轨迹-任务结束”时，记操作时间为当前时间，用于展示在救援信息列表中，相当于状态回写接口报文中的操作时间。

        orderTrackEntity.setIsDelete(0);
        orderTrackEntity.setCreateTime(currentDate);
        orderTrackEntity.setCreater(sourceName01);
        orderTrackEntity.setUpdateTime(currentDate);
        orderTrackEntity.setUpdater(sourceName01);
        orderTrackService.insert(orderTrackEntity);
    }


}
